package com.framework.common.dataTypeConfig.json;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.framework.common.annotation.DataType;
import com.framework.common.dataTypeConfig.core.ReplaceInterface;
import com.framework.common.dataTypeConfig.handler.ReplaceBeanSerializerModifier;
import com.framework.common.dataTypeConfig.handler.ReplaceHandler;
import com.framework.common.model.jackson.BigNumberSerializer;
import com.framework.common.util.date.DateStyleUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

/**
 * @author 龘鵺
 * @className com.framework.common.dataTypeConfig
 * @description json转化初始化配置类
 * @datetime 2025-01-09 11:11:11
 * @version 1.0
 */
@Configuration
public class DataTypeConfig {
    private Logger log = LoggerFactory.getLogger(DataTypeConfig.class);
    @Autowired
    private List<ReplaceInterface<?>> replaceInterfaceList;

    /**
     * @title 配置JSON转化初始设置
     * @description 配置JSON转化初始设置
     * @author 龘鵺
     * @datetime 2025-01-09 11:11:11
     * @param jackson2ObjectMapperBuilder 1
     * @return com.fasterxml.jackson.databind.ObjectMapper
     */
    @Bean
    @Primary
    @ConditionalOnMissingBean(ObjectMapper.class)
    public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder) {
//        ObjectMapper objectMapper = new ObjectMapper();
        ObjectMapper objectMapper = jackson2ObjectMapperBuilder.createXmlMapper(false).build();
        Map<String, ReplaceInterface<?>> map = new HashMap<>(replaceInterfaceList.size());
        for (ReplaceInterface<?> item : replaceInterfaceList) {
            if (item.getClass().isAnnotationPresent(DataType.class)) {
                DataType annotation = item.getClass().getAnnotation(DataType.class);
                map.put(annotation.type(), item);
            } else {
                log.warn("{} 替换实现类未标注 DataDictType 注解!", item.getClass().getName());
            }
        }
        ReplaceHandler.TRANSLATION_MAPPER.putAll(map);
        //处理数字类型大于指定长度出现精度丢失转字符串 - 开始
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(Long.class, BigNumberSerializer.instance);
        javaTimeModule.addSerializer(Long.TYPE, BigNumberSerializer.instance);
        javaTimeModule.addSerializer(BigInteger.class, BigNumberSerializer.instance);
        javaTimeModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
        //格式化日期
        objectMapper.setDateFormat(new SimpleDateFormat(DateStyleUtil.FORMAT_YYYY_MM_DD_HH_MM_SS));
        //处理数字类型大于指定长度出现精度丢失转字符串 - 结束
        //JSON parse error: Unrecognized field 此异常添加处理
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).setSerializationInclusion(JsonInclude.Include.NON_NULL);
        // 设置 Bean 序列化修改器
        return objectMapper.setSerializerFactory(
                objectMapper.getSerializerFactory()
                        .withSerializerModifier(new ReplaceBeanSerializerModifier())).registerModules(javaTimeModule).setTimeZone(TimeZone.getDefault());
    }
}
